package org.smartboot.flow.core.parser.definition;

import org.smartboot.flow.core.Validator;
import org.smartboot.flow.core.common.Uniqueness;
import org.smartboot.flow.core.attribute.AttributeHolder;
import org.smartboot.flow.core.executable.ExecutableAdapter;
import org.smartboot.flow.core.parser.DefinitionVisitor;
import org.smartboot.flow.core.parser.ElementUtils;
import org.smartboot.flow.core.parser.ParseConstants;
import org.smartboot.flow.core.parser.ParserContext;
import org.w3c.dom.Element;

import java.util.ArrayList;
import java.util.List;

/**
 * @author qinluo
 * @date 2022-11-15 13:00:20
 * @since 1.0.0
 */
public class ElementDefinition extends Uniqueness implements Validator {

    protected String name;
    private String execute;
    private String test;
    private String when;
    protected ParserContext context;
    private final List<AttributeHolder> attributes = new ArrayList<>();
    protected volatile boolean visitCalled = false;

    @Override
    public void validate() {

    }

    public void visit(DefinitionVisitor visitor) {
        if (this.visitCalled) {
            return;
        }

        this.visitCalled = true;
        this.visit0(visitor);
    }

    protected void visit0(DefinitionVisitor visitor) {
        visitor.visitBasic(this);
    }

    public Class<?> resolveType() {
        return ExecutableAdapter.class;
    }

    public static void build(ElementDefinition definition, Element element) {
        definition.setName(element.getAttribute(ParseConstants.NAME));
        definition.setExecute(element.getAttribute(ParseConstants.EXECUTE));
        definition.setWhen(element.getAttribute(ParseConstants.WHEN));
        // Extra well-known attributes.
        definition.getAttributes().addAll(ElementUtils.extraAttributes(element));
    }

    public String getExecute() {
        return execute;
    }

    public void setExecute(String execute) {
        this.execute = execute;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<AttributeHolder> getAttributes() {
        return attributes;
    }

    public String getTest() {
        return test;
    }

    public void setTest(String test) {
        this.test = test;
    }

    public String getWhen() {
        return when;
    }

    public void setWhen(String when) {
        this.when = when;
    }

    public ParserContext getContext() {
        return context;
    }

    public void setContext(ParserContext context) {
        this.context = context;
    }
}
